package com.oanda.blackberry.view;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.PasswordEditField;
import net.rim.device.api.ui.component.RadioButtonGroup;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;
import net.rim.device.api.ui.decor.BorderFactory;

import com.oanda.blackberry.net.RestException;
import com.oanda.blackberry.ui.BitmapButtonField;
import com.oanda.blackberry.ui.ColoredCheckboxField;
import com.oanda.blackberry.ui.ColoredRadioButtonField;
import com.oanda.blackberry.ui.OandaMainScreen;
import com.oanda.blackberry.ui.SpacerField;
import com.oanda.blackberry.ui.SpacerManager;
import com.oanda.blackberry.util.AbstractViewPanel;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.Model;
import com.oanda.blackberry.util.PropertyChangeEvent;
import com.oanda.blackberry.util.Settings;
import com.oanda.blackberry.util.UserSettings;
import com.oanda.blackberry.util.log.Logger;

public class LoginView extends OandaMainScreen implements AbstractViewPanel {
    BasicEditField userName = new BasicEditField("", "USERNAME", 40, 2147483648L) {
        public boolean isFocusable() {
            return true;
        }

        protected void onFocus(int direction) {
            if (getText().equals("USERNAME"))
                setText("");
            invalidate();
            super.onFocus(direction);
        }

        protected void onUnfocus() {
            if (getText().equals(""))
                setText("USERNAME");
            invalidate();
            super.onUnfocus();
        }

        public void paint(Graphics g) {
            g.setColor(3355443);
            super.paint(g);
        }
    };

    PasswordEditField password = new PasswordEditField("", "PASSWORD", 40, 2147483648L) {
        public boolean isFocusable() {
            return true;
        }

        protected void onFocus(int direction) {
            if (getText().equals("PASSWORD"))
                setText("");
            invalidate();
            super.onFocus(direction);
        }

        protected void onUnfocus() {
            if (getText().equals(""))
                setText("PASSWORD");
            invalidate();
            super.onUnfocus();
        }

        public void paint(Graphics g) {
            g.setColor(3355443);
            super.paint(g);
        }
    };

    BitmapButtonField login = new BitmapButtonField(
            Bitmap.getBitmapResource("loginButtonSelected-193x73_p24.png"),
            Bitmap.getBitmapResource("loginButton-193x73_p24.png"), "LOGIN", 65536L);

    RadioButtonGroup group = new RadioButtonGroup();

    ColoredCheckboxField save = new ColoredCheckboxField(14540253, "REMEMBER PASSWORD", false,
            8589934592L);
    DefaultController controller;
    int fontHeight = 24;

    int BG_COLOR = 4473924;

    ColoredRadioButtonField fxGame = new ColoredRadioButtonField(14540253, "fxTrade Practice");

    ColoredRadioButtonField fxTrade = new ColoredRadioButtonField(14540253, "fxTrade");

    BitmapButtonField register = new BitmapButtonField(
            Bitmap.getBitmapResource("button_login_new_account_selected.png"),
            Bitmap.getBitmapResource("button_login_new_account.png"), "REGISTER", 65536L);

    MenuItem aboutMenuItem = new MenuItem("About", 10, 1001) {
        public void run() {
            DefaultController.inform("Todo - fill in about information");
        }
    };

    MenuItem loginMenuItem = new MenuItem("Login", 9, 1000) {
        public void run() {
            LoginView.this.login();
        }
    };

    MenuItem registerMenuItem = new MenuItem("Create account", 9, 1000) {
        public void run() {
            LoginView.this.register();
        }
    };

    MenuItem optionsMenuItem = new MenuItem("Options", 10, 1000) {
        public void run() {
            LoginView.this.controller.showOptions();
        }
    };

    MenuItem exitMenuItem = new MenuItem("Exit", 10, 1001) {
        public void run() {
            LoginView.this.controller.exit();
        }
    };

    MenuItem debugMenu = new MenuItem("Debug Menu", 1000, 20004) {
        public void run() {
            LoginView.this.controller.propertyChange(new PropertyChangeEvent(this, "showMenuView",
                    LoginView.this.controller, LoginView.this.controller));
        }
    };

    MenuItem debugMenuYesNoD = new MenuItem("Debug Menu YES/NO", 1000, 20004) {
        public void run() {
            StatusView2.showInfoYesNoDialog(
                    "This is not very long message where I should choose yes or no?",
                    new OKDialogListener() {
                        public void performAction(Object o) {
                            DefaultController.inform((((Boolean[]) (Boolean[]) o)[0].booleanValue() ? " Yes "
                                    : " No ")
                                    + (((Boolean[]) (Boolean[]) o)[1].booleanValue() ? " Checked "
                                            : " NotChecked "));
                        }
                    });
        }
    };

    public LoginView() {
    }

    public LoginView(DefaultController contr) {
        this.controller = contr;
        updateTitle(Model.getVERSION());
        try {
            FontFamily ff = FontFamily.forName("BBAlpha Sans");
            Font defaultFont = ff.getFont(1, this.fontHeight);
            this.save.setFont(defaultFont);
            this.userName.setFont(defaultFont);
            this.password.setFont(defaultFont);
            this.login.setFont(defaultFont);
            this.fxGame.setFont(defaultFont);
            this.fxTrade.setFont(defaultFont);
        } catch (ClassNotFoundException n) {
        }
        Bitmap header = Bitmap.getBitmapResource("header-480x97.png");
        BitmapField headerBitmapField = new BitmapField(header);
        add(headerBitmapField);

        add(new SpacerField(300, 10));

        this.group.add(this.fxGame);
        this.group.add(this.fxTrade);

        add(new SpacerField(300, 10));

        Background solidBackground = BackgroundFactory.createLinearGradientBackground(16777215,
                14540253, 16777215, 14540253);

        Background greyBg = BackgroundFactory.createSolidBackground(this.BG_COLOR);
        setBackground(greyBg);

        getMainManager().setBackground(greyBg);
        this.userName.setBackground(solidBackground);
        this.password.setBackground(solidBackground);

        HorizontalFieldManager hServer = new HorizontalFieldManager(1152921504606846976L);

        hServer.add(new SpacerField(50, 20));
        hServer.add(this.fxGame);
        hServer.add(new SpacerField(20, 20));
        hServer.add(this.fxTrade);

        hServer.setBackground(greyBg);
        add(hServer);

        add(new SpacerField(300, 10));
        add(new SeparatorField());

        HorizontalFieldManager row1 = new HorizontalFieldManager(1152921504606846976L);
        row1.add(new SpacerField(30, 1));
        SpacerManager usm = new SpacerManager(193, 50);
        usm.add(this.userName);
        row1.add(usm);
        row1.add(new SpacerField(20, 1));
        SpacerManager psm = new SpacerManager(193, 50);
        psm.add(this.password);
        row1.add(psm);
        row1.add(new SpacerField(30, 1));
        add(row1);

        add(new SpacerField(300, 10));

        HorizontalFieldManager row2 = new HorizontalFieldManager(1152921504606846976L);

        SpacerManager ssm = new SpacerManager(193, 73);
        VerticalFieldManager ssmv = new VerticalFieldManager(1152921504606846976L);
        ssmv.add(new SpacerField(1, 10));
        ssmv.add(this.save);
        ssm.add(ssmv);
        row2.add(ssm);
        row2.add(new SpacerField(45, 1));
        SpacerManager lsm = new SpacerManager(193, 73);
        lsm.add(this.login);
        row2.add(lsm);
        row2.add(new SpacerField(30, 1));
        add(row2);

        add(new SpacerField(300, 10));
        add(new SeparatorField());
        add(new SpacerField(300, 10));

        HorizontalFieldManager row3 = new HorizontalFieldManager(1152921504606846976L);
        row3.add(new SpacerField(30, 1));
        row3.add(this.register);
        add(row3);

        add(new SpacerField(300, 10));

        this.userName.setBorder(BorderFactory.createRoundedBorder(new XYEdges(3, 3, 3, 3)));
        this.password.setBorder(BorderFactory.createRoundedBorder(new XYEdges(3, 3, 3, 3)));

        HorizontalFieldManager h = new HorizontalFieldManager();

        VerticalFieldManager v3 = new VerticalFieldManager(1152921504606846976L);

        this.group.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                if (LoginView.this.group != null)
                    LoginView.this.controller.onPlatformSelected(LoginView.this.group
                            .getSelectedIndex());
            }
        });
        this.login.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                LoginView.this.login();
            }
        });
        this.register.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                LoginView.this.register();
            }
        });
        addMenuItem(this.aboutMenuItem);
    }

    private void login() {
        this.controller.obtainSessionToken(this.userName.getText(), this.password.getText(),
                this.save.getChecked());
    }

    private void register() {
        this.controller.register(this.userName.getText());
    }

    public void modelPropertyChange(final PropertyChangeEvent evt) {
        Logger.log("LoginView model property change: " + evt.getPropertyName());

        if ((evt.getPropertyName() != null) && (evt.getPropertyName().equals("setErrorMessage"))) {
            if ((evt.getNewValue() != null) && ((evt.getNewValue() instanceof String))) {
                String statusText = (String) evt.getNewValue();
                diplayError(statusText, 3000);
            }
        } else if ((evt.getPropertyName() != null)
                && (evt.getPropertyName().equals("LoginException"))) {
            if ((evt.getNewValue() != null) && ((evt.getNewValue() instanceof RestException))) {
                RestException ex = (RestException) evt.getNewValue();
                if ((ex != null) && (ex.getResponseCode() == 401)
                        && (ex.getReponseMessage().toLowerCase().indexOf("unauthorized") > -1)
                        && (ex.getErrorMessage().toLowerCase().indexOf("access denied") > -1)) {
                    diplayError("Login Failed: Wrong username/password", 5000);
                } else if ((ex != null)
                        && (ex.getResponseCode() == 401)
                        && (ex.getReponseMessage().toLowerCase().indexOf("unauthorized") > -1)
                        && ((ex.getErrorMessage().toLowerCase().indexOf("48: client needs") > -1) || (ex
                                .getErrorMessage().toLowerCase().indexOf("49: client needs") > -1))) {
                    openOtpHelpPage();
                } else {
                    diplayError("Try again! " + ex.getMessage(), 5000);
                }
            }
        } else if ((evt.getPropertyName() != null)
                && (evt.getPropertyName().equals("setStatusMessage"))) {
            Logger.log("LoginView setStatusMessage: " + (String) evt.getNewValue());
            if ((evt.getNewValue() != null) && ((evt.getNewValue() instanceof String))) {
                String statusText = (String) evt.getNewValue();
                if ((statusText != null) && (statusText.length() > 0)) {
                    setStatusField(statusText);
                } else {
                    setStatusField("");
                    removeStatusField();
                }

            }

        } else if ((evt.getPropertyName() != null)
                && (evt.getPropertyName().equals("sessionToken"))) {
            Logger.log("LogInView: -" + (String) evt.getNewValue() + "-");
        } else if ((evt.getPropertyName() != null) && (evt.getPropertyName().equals("setSettings"))) {
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                private final PropertyChangeEvent _evt = evt;

                public void run() {
                    if ((this._evt.getNewValue() != null)
                            && ((this._evt.getNewValue() instanceof Settings))) {
                        Settings set = (Settings) this._evt.getNewValue();
                        int index = set.getUrlIndex();

                        LoginView.this.group.setSelectedIndex(index);
                        if (set.getUserAccountSettings(index) != null) {
                            String usern = set.getUserAccountSettings(index).getUsername();
                            String passw = set.getUserAccountSettings(index).getPassword();
                            if (usern != null) {
                                if (usern.equals(""))
                                    LoginView.this.userName.setText("USERNAME");
                                else
                                    LoginView.this.userName.setText(usern);
                            }
                            if (passw != null) {
                                if (passw.equals(""))
                                    LoginView.this.password.setText("PASSWORD");
                                else
                                    LoginView.this.password.setText(passw);
                            }
                            LoginView.this.save.setChecked(set.getUserAccountSettings(index)
                                    .isSave());
                        } else {
                            Logger.log("LoginView getUserAccountSettings = null");
                        }
                    } else {
                        Logger.log("LoginView settings = null");
                    }
                }
            });
        } else if ((evt.getPropertyName() == null)
                || (!evt.getPropertyName().equals("setUserSettings"))) {
            if ((evt.getPropertyName() != null) && (evt.getPropertyName().equals("setUrlIndex"))) {
                UiApplication app = UiApplication.getUiApplication();

                if (app == null)
                    return;

                app.invokeLater(new Runnable() {
                    private final PropertyChangeEvent _evt = evt;

                    public void run() {
                        if ((LoginView.this.group != null) && (this._evt.getNewValue() != null)
                                && (this._evt.getOldValue() != null)
                                && (this._evt.getNewValue() != this._evt.getOldValue())) {
                            int index = ((Integer) this._evt.getNewValue()).intValue();
                            LoginView.this.group.setSelectedIndex(index);

                            UserSettings set = Model.getModel().getSettings()
                                    .getUserAccountSettings(index);
                            if ((set != null) && (set.isSave())) {
                                String usern = set.getUsername();
                                String passw = set.getPassword();
                                if (usern != null) {
                                    if (usern.equals(""))
                                        LoginView.this.userName.setText("USERNAME");
                                    else {
                                        LoginView.this.userName.setText(usern);
                                    }
                                }
                                if (passw != null) {
                                    if (passw.equals(""))
                                        LoginView.this.password.setText("PASSWORD");
                                    else {
                                        LoginView.this.password.setText(passw);
                                    }
                                }
                                LoginView.this.save.setChecked(set.isSave());
                            } else if ((set != null) && (!set.isSave())) {
                                LoginView.this.userName.setText("USERNAME");
                                LoginView.this.password.setText("PASSWORD");
                                LoginView.this.save.setChecked(false);
                            } else {
                                Logger.log("LoginView Model.getModel().getSettings().getUserAccountSettings(index);");
                            }
                        }
                    }

                });
            } else if ((evt.getPropertyName() != null)
                    && (evt.getPropertyName().equals("showLogin"))) {
                this.controller.pushScreen(this);
            } else if ((evt.getPropertyName() != null)
                    && (evt.getPropertyName().equals("hideLogin"))) {
                this.controller.popScreen(this);
            } else if ((evt != null) && (evt.getPropertyName().equals("showThrobber"))) {
                showThrobber();
            } else if ((evt != null) && (evt.getPropertyName().equals("hideThrobber"))) {
                hideThrobber();
            }
        }
    }

    private void openOtpHelpPage() {
        this.controller.displayOtpHelp();
    }

    protected void makeMenu(Menu menu, int instance) {
        menu.add(this.loginMenuItem);
        menu.add(this.registerMenuItem);
        menu.add(this.optionsMenuItem);
        menu.add(this.exitMenuItem);
    }

    public boolean onClose() {
        this.controller.exit();
        return true;
    }

    public void invalidate() {
        super.invalidate();
    }

    protected void onUiEngineAttached(boolean attached) {
        if (attached) {
            hideThrobber();
            Runnable r = new Runnable() {
                public void run() {
                    LoginView.this.controller.showInternetTrafficWarning();
                }
            };
            new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(100L);
                    } catch (InterruptedException ex) {
                    }
                }
            }).start();
        }
    }
}
